【笔记】修复Linux引导文件
(2024.10.23)
基础内容
从加电到出现登录界面,大致流程分为四个阶段:
- BIOS/UEFI 启动阶段
- POST (Power on Self Test)
- 加载 bootloader,并把控制权转交给 bootloader
- 内核引导阶段
该阶段核心功能是加载内核镜像 vmlinuz 以及 initramfs 到内存,并将控制权交给内核。- BIOS/MS-DOS
- UEFI/GPT
- 内核启动阶段
- 服务启动阶段
GRUB的工作流程可以分为以下几个步骤:
- 加载阶段:当计算机启动时,BIOS或UEFI固件会加载GRUB的第一阶段代码(通常位于磁盘的引导扇区)。
- 加载配置:GRUB读取其配置文件(如
grub.cfg
),了解可用的操作系统和内核选项。 - 用户交互:在配置文件的指引下,GRUB显示启动菜单,允许用户选择启动项。
- 引导内核:根据用户选择,GRUB加载并传递内核启动参数给操作系统内核,完成系统启动。
大致思路:挂载镜像,安装kernel(会自动在/boot下生成vmlinz和initramfs文件)、为系统盘安装grub引导、修改grub配置文件
需要知道的信息:文件系统保存在哪块硬盘上,要在这块硬盘上装grub引导
参考:
grub2详解 https://www.cnblogs.com/f-ck-need-u/p/7094693.html
BIOS模式下
模拟环境
系统:redhat 6.4
1 |
|
删除/boot文件下所有文件:rm -rf /boot/*
重启系统后报错:
修复
挂载镜像进入rescue模式修复
更改方法,挂镜像。无奈开机总是进到命令行,疯狂重启按ESC,终于进去了(小tips,在grub下reboot
连续按ESC好进一些):
选择第三项:
创建光盘挂载目录,并挂载光盘,安装kernel包,会生成/boot目录以及内核及initramfs :
1 |
|
上述图中,可以看到/boot分区在/dev/sda1下,为第一块磁盘安装grub引导修复grub,grub-install /dev/sda
:
会报分区标签的错误,不用理会。查看/boot下生成的文件:
文件都有了,需要写个配置文件,在系统起来时自动查找。
1 |
|
grub.conf配置文件参数补充
- default=0:默认启动第一个系统。也就是说,如果在等待时间结束后,用户没有选择进入哪个系统,那么系统会默认进入第一个系统。如果有多系统并存,那么每个系统都会有自己的 title 字段,如果想要默认进入第二个系统,这里就可以设为 default=1。
- timeout=5:等待时间,默认是 5 秒。也就是在进入系统时,如果 5 秒内用户没有按下任意键,那么系统会进入 default 字段定义的系统。当然,也可以手工修改这个等待时间,如果timeout=0,则不会等待直接进入系统;如果 timeout=-1,则会一直等待用户输入,而不会自动进入系统。
- hiddenmenu:隐藏菜单。启动时默认只能看到读秒,而不能看到菜单。如果想要看到菜单,则需要按任意键。如果注释了这句话,那么启动时就能直接看到菜单了。
- title CentOS(2.6.32-279.d6.i686):title 就是标题的意思,也就是说,在 title 后面写入的是什么,系统启动时在 GRUB 的启动菜单中看到的就是什么。
- root(hd0,0):是指启动程序的保存分区。这里要注意,这个 root 并不是管理员。在我的系统中,/boot 分区是独立划分的,而且设备文件名为 /dev/sda1,所以在 GRUB 中就被描述为 hd(0,0)。
- kernel /vmlinuz-2.6.32-279.el6.i686 ro root=UUID=b9a7a1a8-767f-4a87-8a2b-a535edb362c9 rd_NO_LUKS KEYBOARDTYPE=pc KEYTABLE=us rd_NO_MD crashkernel=auto LANG=zh_CN.UTF-8 rd_NO_LVM rd_NO_DM rhgb quiet。其中:
- /vmlinuz-2.6.32-279.el6.i686:指定了内核文件的位置,这里的 / 是指 boot 分区。
- ro:启动时以只读方式挂载根文件系统,这是为了不让启动过程影响磁盘内的文件系统。
- root=UUID=b9a7a1 a8-767f-4a87-8a2b-a535edb362c9:指定根文件系统的所在位置。这里和以前的Linux版本不太一样了,不再通过分区的设备文件名或卷标号来指定,而是通过分区的 UUID 来指定的。
- rhgb:(redhatgraphics boot)用图片来代替启动过程中的文字信息。启动完成之后可以使用dmesg命令来查看这些文字信息。
- quiet:隐藏启动信息,只显示重要信息。
- initrd/initramfs-2.6.32-279.el6.i686.img:指定了initramfs虚拟文件系统镜像文件的所在位置。
重启后即可进入系统
临时修复
一般来说,查到的很多资料是可以在grub >
下直接ls
就能看到对应的分区或者驱动器,比如:
手动在grub命令行中敲命令,不过只能一次,重启丢失,所以还是建议启动后写到配置文件中~
本次实验环境无法ls
,使用root [DEVICE [HDBIAS]]
加上TAB;输入root (hd0,然后按tab键,会有如下显示:
有些硬盘没有分区,TA不能补全的肯定就不是啦,比如hd1
:
需要把type 0x83的分区位置都得试一下,因为0x83的分区都有可能是/root分区,即part0或part1。
1 |
|
参考:https://www.pianshen.com/article/16761644613/#google_vignette
EFI
模拟环境
模拟环境,删除/boot下的所有文件。重启系统:
修复
挂载镜像进入救援模式:
首先确保分区还在,数据也都在:
进到/boot目录下,可以看到只有一个空的efi
文件夹,重新更新安装一遍kernel服务。把镜像挂载给/mnt/cdrom
,进入/mnt/cdrom/Packages
,安装kernel。在安装完kernel之后,生成了vmlinuz和initramfs文件:
这时/boot/efi
目录下还是空的,还需要再安装grub和shim引导:
安装的已经装了,还差grub.cfg
配置文件。提前瞅一眼/boot/efi/EFI/
下的发行版本是啥,输入grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg
重新生成一下grub.cfg配置文件(大部分情况自动生成的是可以满足的)
这个时候就能够重启系统正常进入了。有一些手册还有个命令是grub2-install /dev/sda,也是安装grub,/dev/sda是系统所在盘,这条命令依赖于/usr/lib/grub/x86_64-efi目录,但我的系统好想本身就没有,所以敲上之后会有报错。解决的话,可以exit退出到rescue的bash模式下
# cp -R /usr/lib/grub/x86_64-efi/* /mnt/sysimage/usr/lib/grub/x86_64-efi/
,然后使用chroot切换到/mnt/sysimage环境,继续运行# grub2-install /dev/sdb1
,即可成功安装grub2,再继续生成grub.cfg
配置文件。(红帽官方BIOS模式使用grub-install,UEFI使用rpm/yum安装)